#ifndef __VECTOR2_H__
#define __VECTOR2_H__

#pragma once

#include "Evaluation.h"

namespace Nezha
{

	class NEZHA_ENGINE_ENTRY Vector2
	{
	public:
		Vector2() {}
		Vector2(Real fX, Real fY)
			:x(fX), y(fY)
		{
		}

		Real& operator[] (int i)
		{
			const Real* p = &x;
			return (Real&) p[i];
		}

		const Real& operator[] (int i) const
		{
			const Real* p = &x;
			return (Real&) p[i];
		}

		bool operator == (const Vector2& pt) const
		{
			return x == pt.x && y == pt.y;
		}

		bool operator != (const Vector2& pt) const
		{
			return x != pt.x || y != pt.y;
		}

		Vector2 operator + (const Vector2& pt) const
		{
			return Vector2(x+pt.x, y+pt.y);
		}

		Vector2 operator - (const Vector2& pt) const
		{
			return Vector2(x-pt.x, y-pt.y);
		}

		Real operator * (const Vector2& pt) const
		{
			return x*pt.x + y*pt.y;
		}

		Vector2 operator * (Real scalar) const
		{
			return Vector2(x*scalar, y*scalar);
		}

		Vector2 operator / (Real scalar) const
		{
			return Vector2(x/scalar, y/scalar);
		}

		Vector2 operator - () const
		{
			return Vector2(-x, -y);
		}

		friend Vector2 operator * (Real scalar,
			const Vector2& pt)
		{
			return pt*scalar;
		}

		static Vector2 componentProduct(const Vector2& p0, const Vector2& p1)
		{
			return Vector2(p0.x*p1.x, p0.y*p1.y);
		}

		Vector2& operator += (const Vector2& pt)
		{
			x += pt.x;
			y += pt.y;
			return *this;
		}

		Vector2& operator -= (const Vector2& pt)
		{
			x -= pt.x;
			y -= pt.y;
			return *this;		
		}

		Vector2& operator *= (Real scalar)
		{
			x *= scalar;
			y *= scalar;
			return *this;
		}

		Vector2& operator /= (Real scalar)
		{
			Real inv = (Real)1.0 / scalar;
			x *= scalar;
			y *= scalar;
			return *this;
		}

		Real length() const
		{
			return Sqrt(x*x + y*y);
		}

		Real sqrLength() const
		{
			return x*x + y*y;
		}

		Real dot(const Vector2& pt) const
		{
			return x*pt.x + y*pt.y;
		}

		Real normalize()
		{
			Real len = length();

			if(len > NZ_TOLERANCE)
			{
				Real inv = (Real)1.0 / len;
				x *= inv;
				y *= inv;
			}
			else
			{
				x = y = len = 0.0;
			}

			return len;
		}

		Real x, y;

		static const Vector2 ZERO;
		static const Vector2 UNIT_X;
		static const Vector2 UNIT_Y;
	};

} //end namespace Nezha

#endif //end __VECTOR2_H__